<template>
  <div class="uploader">
    <slot :files="files" :file-list="fileList" :started="started">
      <ChunkFileUploaderUnSupport />
      <ChunkFileUploaderDrop>
        <p>Drop files here to upload or</p>
        <ChunkFileUploaderButton>select files</ChunkFileUploaderButton>
        <ChunkFileUploaderButton :directory="true">select folder</ChunkFileUploaderButton>
      </ChunkFileUploaderDrop>
      <ChunkFileUploaderList />
    </slot>
  </div>
</template>

<script>
  import Uploader from 'simple-uploader.js'
  import { kebabCase } from '../common/utils'
  import ChunkFileUploaderUnSupport from './ChunkFileUploaderUnSupport'
  import ChunkFileUploaderDrop from './ChunkFileUploaderDrop'
  import ChunkFileUploaderList from './ChunkFileUploaderList'
  import ChunkFileUploaderButton from './ChunkFileUploaderButton'

  const FILE_ADDED_EVENT = 'fileAdded'
  const FILES_ADDED_EVENT = 'filesAdded'
  const UPLOAD_START_EVENT = 'uploadStart'

  export default {
    name: 'ChunkFileUploader',
    components: { ChunkFileUploaderButton, ChunkFileUploaderList, ChunkFileUploaderDrop, ChunkFileUploaderUnSupport },
    provide() {
      return {
        uploader: this
      }
    },
    props: {
      options: {
        type: Object,
        default() {
          return {}
        }
      },
      autoStart: {
        type: Boolean,
        default: true
      },
      fileStatusText: {
        type: [Object, Function],
        default() {
          return {
            success: 'success',
            error: 'error',
            uploading: 'uploading',
            paused: 'paused',
            waiting: 'waiting'
          }
        }
      }
    },
    data() {
      return {
        started: false,
        files: [],
        fileList: []
      }
    },
    created() {
      // this.options.initialPaused = !this.autoStart
      const uploader = new Uploader({ ...this.options, initialPaused: !this.autoStart })
      this.uploader = uploader
      this.uploader.fileStatusText = this.fileStatusText
      uploader.on('catchAll', this.allEvent)
      uploader.on(FILE_ADDED_EVENT, this.fileAdded)
      uploader.on(FILES_ADDED_EVENT, this.filesAdded)
      uploader.on('fileRemoved', this.fileRemoved)
      uploader.on('filesSubmitted', this.filesSubmitted)
    },
    destroyed() {
      const uploader = this.uploader
      uploader.off('catchAll', this.allEvent)
      uploader.off(FILE_ADDED_EVENT, this.fileAdded)
      uploader.off(FILES_ADDED_EVENT, this.filesAdded)
      uploader.off('fileRemoved', this.fileRemoved)
      uploader.off('filesSubmitted', this.filesSubmitted)
      this.uploader = null
    },
    methods: {
      uploadStart() {
        this.started = true
      },
      fileAdded(file) {
        this.$emit(kebabCase(FILE_ADDED_EVENT), file)
        if (file.ignored) {
          // is ignored, filter it
          return false
        }
      },
      filesAdded(files, fileList) {
        this.$emit(kebabCase(FILES_ADDED_EVENT), files, fileList)
        if (files.ignored || fileList.ignored) {
          // is ignored, filter it
          return false
        }
      },
      fileRemoved(file) {
        this.$emit('file-removed', file)
        this.files = this.uploader.files
        this.fileList = this.uploader.fileList
      },
      filesSubmitted(files, fileList) {
        this.files = this.uploader.files
        this.fileList = this.uploader.fileList
        if (this.autoStart) {
          this.uploader.upload()
        }
      },
      allEvent(...args) {
        const name = args[0]
        const EVENTSMAP = {
          [FILE_ADDED_EVENT]: true,
          [FILES_ADDED_EVENT]: true,
          [UPLOAD_START_EVENT]: 'uploadStart'
        }
        const handler = EVENTSMAP[name]
        if (handler) {
          if (handler === true) {
            return
          }
          this[handler].apply(this, args.slice(1))
        }
        args[0] = kebabCase(name)
        this.$emit.apply(this, args)
      }
    }
  }
</script>

<style>
  .uploader {
    position: relative;
  }
</style>
